part of 'page.dart';

class _CollectionSelectionPageWloc
    extends StatefulWloc<_CollectionSelectionPageWlocState, CollectionSelectionPage>
    with SingleTickerProviderStateMixin {
  late final bloc.CollectionSelectionPageBloc _bloc;

  late Map<Type, NavigationBarTextButtonAutoSizeGroup> navigationButtonAutoSizeGroups;
  late final TextEditingController textEditingController;
  late FocusNode textFieldFocusNode;
  late AnimationController shakeAnimationController;

  @override
  _CollectionSelectionPageWlocState get initialState {
    return _CollectionSelectionPageWlocStateFactory().create(
      blocState: _bloc.state,
      context: context,
    );
  }

  /////////////////////////////////////////////////////////////////////////////////////////////////
  /// [_DefaultState]
  /////////////////////////////////////////////////////////////////////////////////////////////////
  // <editor-fold defaultstate="collapsed">

  void onCollectionListItemReorderingIconPressed() {
    _bloc.requestCollectionListItemReorderingStart();
  }

  void onCollectionListItemCreationIconPressed() {
    _bloc.requestCollectionListItemCreationStart();
  }

  void onCollectionCheckboxPressed({
    required _CollectionModel collectionModel,
  }) {
    _bloc.requestCollectionSelectionToggling(
      collectionId: collectionModel.id,
    );
  }

  void onCollectionTilePressed({
    required String collectionId,
  }) {
    _bloc.requestSingleCollectionPageOpening(
      collectionId: collectionId,
    );
  }

  void onCustomCollectionFolderTilePressed({
    required String customCollectionFolderId,
  }) {
    _bloc.requestSingleCustomCollectionFolderPageOpening(
      customCollectionFolderId: customCollectionFolderId,
    );
  }

  void onSearchIconButtonPressed() {
    _bloc.requestAllLexicalItemPageOpening();
  }

  Future<void> _showCollectionListItemCreationDialog({
    required _DefaultState state,
  }) async {
    final collectionListItemType = await showAppActionDialog<Type?>(
      context: context,
      builder: (context) {
        return AppActionDialog(
          actions: [
            AppActionDialogAction(
              title: CollectionSelectionPageTranslation.of(context)
                  .collectionCreationDialogActionTitle,
              showPremiumBadge: !state.collectionListItemCreationPermitted,
              onPressed: () {
                Navigator.of(context).pop(CustomCollection);
              },
            ),
            AppActionDialogAction(
              title: CollectionSelectionPageTranslation.of(context)
                  .collectionFolderCreationDialogActionTitle,
              showPremiumBadge: !state.collectionListItemCreationPermitted,
              onPressed: () {
                Navigator.of(context).pop(CustomCollectionFolder);
              },
            ),
          ],
          onCancelButtonPressed: Navigator.of(context).pop,
        );
      },
    );

    if (collectionListItemType == CustomCollection) {
      _bloc.requestCollectionCreationStart();
    } else if (collectionListItemType == CustomCollectionFolder) {
      _bloc.requestCollectionFolderCreationStart();
    }
  }

  // </editor-fold>

  /////////////////////////////////////////////////////////////////////////////////////////////////
  /// [_CollectionListItemReordering]
  /////////////////////////////////////////////////////////////////////////////////////////////////
  // <editor-fold defaultstate="collapsed">

  void onCollectionListItemReorderingCancellationButtonPressed() {
    _bloc.requestCollectionListItemReorderingCancellation();
  }

  void onCollectionListItemReorderingCompletionButtonPressed() {
    _bloc.requestCollectionListItemReorderingCompletion();
  }

  bool onReorderCollectionListItems(Key draggedItemKey, Key newPositionKey) {
    final _state = state;

    if (_state is _CollectionListItemReordering) {
      final draggingIndex = _getReorderableCollectionListItemModelIndexByKey(
        reorderedCollectionListItemModels: _state.reorderedCollectionListItemModels,
        key: draggedItemKey,
      );

      final newPositionIndex = _getReorderableCollectionListItemModelIndexByKey(
        reorderedCollectionListItemModels: _state.reorderedCollectionListItemModels,
        key: newPositionKey,
      );

      _bloc.requestReorderableCollectionListItemSwap(
        firstIndex: draggingIndex,
        secondIndex: newPositionIndex,
      );
    }

    return true;
  }

  Key getReorderableCollectionListItemModelKey(_CollectionListItemModel collectionListItemModel) {
    return Key(collectionListItemModel.hashCode.toString());
  }

  int _getReorderableCollectionListItemModelIndexByKey({
    required Key key,
    required BuiltList<_CollectionListItemModel> reorderedCollectionListItemModels,
  }) {
    return reorderedCollectionListItemModels.indexWhere((collectionListItemModel) {
      final collectionListItemModelKey =
          getReorderableCollectionListItemModelKey(collectionListItemModel);
      return collectionListItemModelKey == key;
    });
  }

  // </editor-fold>

  /////////////////////////////////////////////////////////////////////////////////////////////////
  /// [_CollectionCreation]
  /////////////////////////////////////////////////////////////////////////////////////////////////
  // <editor-fold defaultstate="collapsed">

  void onCollectionCreationCancellationButtonPressed() {
    _bloc.requestCollectionCreationCancellation();
  }

  void onCollectionCreationCompletionButtonPressed() {
    textFieldFocusNode.requestFocus();

    final collectionTitle = textEditingController.text.trim();
    textEditingController.text = collectionTitle;

    _bloc.requestCollectionCreationCompletion(
      collectionTitleInput: collectionTitle,
    );
  }

  // </editor-fold>

  /////////////////////////////////////////////////////////////////////////////////////////////////
  /// [_CollectionFolderCreation]
  /////////////////////////////////////////////////////////////////////////////////////////////////
  // <editor-fold defaultstate="collapsed">

  void onCollectionFolderCreationCancellationButtonPressed() {
    _bloc.requestCollectionFolderCreationCancellation();
  }

  void onCollectionFolderCreationCompletionButtonPressed() {
    textFieldFocusNode.requestFocus();

    final collectionFolderTitle = textEditingController.text.trim();
    textEditingController.text = collectionFolderTitle;

    _bloc.requestCollectionFolderCreationCompletion(
      collectionFolderTitleInput: collectionFolderTitle,
    );
  }

  // </editor-fold>

  void _onBlocStateChanged(
      (
        bloc.CollectionSelectionPageBlocState,
        bloc.CollectionSelectionPageBlocState
      ) valueWithPrevious) {
    final (blocState, blocPreviousState) = valueWithPrevious;

    final updatedState = _CollectionSelectionPageWlocStateFactory().create(
      blocState: blocState,
      context: context,
    );

    emit(updatedState);

    if (blocState is bloc.DefaultState) {
      if (blocState.collectionListItemCreationDialogShown) {
        _showCollectionListItemCreationDialog(
          state: updatedState as _DefaultState,
        );
      }
    } else if (blocState is bloc.CollectionCreation) {
      if (blocState.validationError != null) {
        shakeAnimationController.forward(from: 0.0);
      }
    } else if (blocState is bloc.CollectionFolderCreation) {
      if (blocState.validationError != null) {
        shakeAnimationController.forward(from: 0.0);
      }
    }

    if (blocPreviousState is bloc.CollectionCreation && blocState is! bloc.CollectionCreation) {
      textEditingController.clear();
    }

    if (blocPreviousState is bloc.CollectionFolderCreation &&
        blocState is! bloc.CollectionFolderCreation) {
      textEditingController.clear();
    }

    if (blocPreviousState is! bloc.CollectionCreation && blocState is bloc.CollectionCreation) {
      textFieldFocusNode.requestFocus();
    }

    if (blocPreviousState is! bloc.CollectionFolderCreation &&
        blocState is bloc.CollectionFolderCreation) {
      textFieldFocusNode.requestFocus();
    }
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();

    final updatedState = _CollectionSelectionPageWlocStateFactory().create(
      blocState: _bloc.state,
      context: context,
    );

    emit(updatedState);
  }

  @override
  void initState() {
    super.initState();

    _bloc = bloc.CollectionSelectionPageBloc(
      learningContentBloc: core_di.sl(),
      userInfoBloc: core_di.sl(),
      overlayBloc: core_di.sl(),
      collectionNavigatorBloc: core_di.sl(),
      purchaseFlowDisplayBloc: core_di.sl(),
      cancelCollectionCreation: collection_selection_page_di.sl(),
      cancelCollectionFolderCreation: collection_selection_page_di.sl(),
      cancelCollectionListItemReordering: collection_selection_page_di.sl(),
      completeCollectionCreation: collection_selection_page_di.sl(),
      completeCollectionFolderCreation: collection_selection_page_di.sl(),
      completeCollectionListItemReordering: collection_selection_page_di.sl(),
      getInitialData: collection_selection_page_di.sl(),
      handleCollectionCreationLearningContentOuterUpdate: collection_selection_page_di.sl(),
      handleCollectionCreationPremiumAccessStatusOuterUpdate: collection_selection_page_di.sl(),
      handleCollectionFolderCreationLearningContentOuterUpdate: collection_selection_page_di.sl(),
      handleCollectionFolderCreationPremiumAccessStatusOuterUpdate:
          collection_selection_page_di.sl(),
      handleCollectionListItemReorderingLearningContentOuterUpdate:
          collection_selection_page_di.sl(),
      handleCollectionListItemReorderingPremiumAccessStatusOuterUpdate:
          collection_selection_page_di.sl(),
      handleDefaultStateLearningContentOuterUpdate: collection_selection_page_di.sl(),
      handleDefaultStatePremiumAccessStatusOuterUpdate: collection_selection_page_di.sl(),
      swapCollectionListItems: collection_selection_page_di.sl(),
      toggleCollectionSelection: collection_selection_page_di.sl(),
    );

    _bloc.streamWithPrevious.listen(_onBlocStateChanged);

    navigationButtonAutoSizeGroups = {
      _CollectionListItemReordering: NavigationBarTextButtonAutoSizeGroup(),
      _CollectionCreation: NavigationBarTextButtonAutoSizeGroup(),
      _CollectionFolderCreation: NavigationBarTextButtonAutoSizeGroup(),
    };

    textEditingController = TextEditingController();
    textFieldFocusNode = FocusNode();

    shakeAnimationController = AnimationController(
      duration: const Duration(milliseconds: 200),
      vsync: this,
    );
  }

  @override
  void dispose() {
    _bloc.close();

    textEditingController.dispose();
    textFieldFocusNode.dispose();

    shakeAnimationController.dispose();

    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return _CollectionSelectionPageView(
      wloc: this,
    );
  }
}
